package com.ruyuan.user.server.controller.converter;

import com.ruyuan.gateway.sdk.facade.RuyuanGatewayFacade;
import com.ruyuan.user.api.model.enums.GenderEnum;
import com.ruyuan.user.api.model.enums.RecruitTypeEnum;
import com.ruyuan.user.api.model.enums.UserJobRelationTypeEnum;
import com.ruyuan.user.server.controller.request.SaveUserMultiJobRequest;
import com.ruyuan.user.server.controller.request.SaveUserRequest;
import com.ruyuan.user.server.controller.response.CurrentUserVO;
import com.ruyuan.user.server.controller.response.MultiJobRelationVO;
import com.ruyuan.user.server.controller.response.UserListInfoVO;
import com.ruyuan.user.server.domain.model.Job;
import com.ruyuan.user.server.domain.model.Organization;
import com.ruyuan.user.server.domain.model.User;
import com.ruyuan.user.server.domain.service.JobDomainService;
import com.ruyuan.user.server.domain.service.OrganizationDomainService;
import com.ruyuan.user.server.domain.service.request.SaveUserMultiJobReq;
import com.ruyuan.user.server.util.OrganizationUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xx
 */
@Component
public class WebUserConverter {

    @Autowired
    private JobDomainService jobDomainService;

    @Autowired
    private OrganizationDomainService organizationDomainService;

    @Autowired
    private RuyuanGatewayFacade ruyuanGatewayFacade;

    public User convertToUser(SaveUserRequest saveUserRequest) {
        User user = new User();
        user.setId(saveUserRequest.getId());
        // 这里我们先写死操作者, 因为我们还没做登录功能, 拿不到当前操作的用户信息
        user.setModifier("admin");
        user.setName(saveUserRequest.getName());
        // 我们不做文件上传的功能, 这里我直接写死一个图片地址
        user.setPhoto("https://img2.woyaogexing.com/2020/06/19/02d268db09ff4e8e9608fd64adbbeed8!400x400.jpeg");
        user.setBirthday(saveUserRequest.getBirthday());
        user.setGender(GenderEnum.getByCode(saveUserRequest.getGender()));
        user.setNation(saveUserRequest.getNation());
        user.setPhone(saveUserRequest.getPhone());
        user.setAddress(saveUserRequest.getAddress());
        user.setEmail(saveUserRequest.getEmail());
        user.setIdentityCardNum(saveUserRequest.getIdentityCardNum());
        if (saveUserRequest.getJobId() != null) {
            Job job = jobDomainService.queryById(saveUserRequest.getJobId());
            if (job != null) {
                user.setMainJob(job);
                user.setRootOrgId(organizationDomainService.queryOrganizationById(job.getOrgId()).getRootId());
            }
        }
        user.setEntryDate(saveUserRequest.getEntryDate());
        user.setBecomeTrailDate(saveUserRequest.getBecomeTrailDate());
        user.setBecomeRegularDate(saveUserRequest.getBecomeRegularDate());
        user.setCode(saveUserRequest.getCode());
        user.setSalary(saveUserRequest.getSalary());
        user.setRecruitType(RecruitTypeEnum.getByCode(saveUserRequest.getRecruitType()));
        user.setLevel(saveUserRequest.getLevel());
        return user;
    }

    public CurrentUserVO convertToCurrentUserVO(User user) {
        CurrentUserVO currentUserVO = new CurrentUserVO();
        BeanUtils.copyProperties(user, currentUserVO);
        Optional.of(user.getGender()).ifPresent(gender -> currentUserVO.setGender(gender.getCode()));
        Optional.of(user.getGender()).ifPresent(gender -> currentUserVO.setGenderLabel(gender.getDescription()));
        Optional.of(user.getRecruitType()).ifPresent(recruitType -> currentUserVO.setRecruitType(recruitType.getCode()));
        Optional.of(user.getRecruitType()).ifPresent(recruitType -> currentUserVO.setRecruitTypeLabel(recruitType.getDescription()));
        Job mainJob = user.getMainJob();
        if (mainJob != null) {
            currentUserVO.setOrgId(mainJob.getOrgId());
            Map<Long, Organization> orgMap = new HashMap<>();
            Organization organization = organizationDomainService.queryOrganizationById(mainJob.getOrgId());
            orgMap.put(organization.getId(), organization);
            organization.getOrgPath().stream().map(organizationDomainService::queryOrganizationById).forEach(org -> orgMap.put(org.getId(), org));
            currentUserVO.setOrgNamePath(OrganizationUtil.buildOrgPathDisplayText(organization, orgMap));
            currentUserVO.setJobName(mainJob.getName());
            currentUserVO.setJobId(mainJob.getId());
        }
        return currentUserVO;
    }

    public List<UserListInfoVO> convertToUserListInfoVO(List<User> userList) {
        //类似岗位，先把需要查的组织查出来保存
        Map<Long, Organization> orgMap = new HashMap<>();
        Set<Long> orgIdSet = userList.stream().map(User::getMainJob).filter(Objects::nonNull).map(Job::getOrgId).collect(Collectors.toSet());
        orgIdSet.forEach(
                orgId -> {
                    Organization organization = organizationDomainService.queryOrganizationById(orgId);
                    if (organization != null) {
                        orgMap.put(orgId, organization);
                    }
                }
        );
        //缓存组织全路径上的组织节点
        Map<Long, Organization> tempMap = new HashMap<>();
        orgMap.values().stream().map(Organization::getOrgPath).filter(CollectionUtils::isNotEmpty)
                .flatMap(Collection::stream).filter(orgId -> !orgMap.containsKey(orgId))
                .distinct().forEach(
                        orgId -> {
                            Organization organization = organizationDomainService.queryOrganizationById(orgId);
                            if (organization != null) {
                                tempMap.put(orgId, organization);
                            }
                        }
                );
        orgMap.putAll(tempMap);
        return userList.stream().map(user -> {
            UserListInfoVO userListInfoVO = new UserListInfoVO();
            BeanUtils.copyProperties(user, userListInfoVO);
            if (user.getMainJob() != null) {
                userListInfoVO.setPosition(user.getMainJob().getName());
                userListInfoVO.setOrgNamePath(OrganizationUtil.buildOrgPathDisplayText(orgMap.get(user.getMainJob().getOrgId()), orgMap));
            }
            return userListInfoVO;
        }).collect(Collectors.toList());
    }

    public SaveUserMultiJobReq convertToSaveUserMultiJobReq(SaveUserMultiJobRequest request) {
        SaveUserMultiJobReq req = new SaveUserMultiJobReq();
        req.setUserId(request.getUserId());
        req.setOperator(String.valueOf(ruyuanGatewayFacade.getCurrentUser().getUserId()));
        req.setUserMultiJob(convertToMultiJob(request.getMultiJobs()));
        return req;
    }

    public Map<UserJobRelationTypeEnum, List<Job>> convertToMultiJob(List<MultiJobRelationVO> multiJobs) {
        Map<UserJobRelationTypeEnum, List<Job>> map = new HashMap<>();
        if (CollectionUtils.isEmpty(multiJobs)) {
            return map;
        }
        multiJobs.forEach(vo -> {
            UserJobRelationTypeEnum type = UserJobRelationTypeEnum.getByCode(vo.getRelationType());
            if (type != null) {
                List<Job> jobs = map.computeIfAbsent(type, typeEnum -> new ArrayList<>());
                Job job = jobDomainService.queryById(vo.getJobId());
                if (job != null) {
                    jobs.add(job);
                }
            }
        });
        return map;
    }

}
